<?php
/**
 *  Generic Default Model: a class for item-based model management:
 *      - the data source is the DB
 *      - the record properties are taken from Module config
 *  Similar to Active Record pattern, in which the record is implemented in Item,
 *      and the data access in Action.
 *
 *  @todo select item externally ? or leave it up to subclass only
 *
 */
namespace Yz\modules\Generic;

class Model_List
    extends Model_Abstract
    implements \Yz_Model_Interface
{


    /************************************
     *          Public methods          *
     ************************************/


    /**
     *
     *  @return Yz_Array[Yz_Item_Interface]
     */
    public function fetchList()
    {
        debug();

        $item = $this->selectItem();

        $action = $this->selectAction('SelectList');
        $action
            ->assignFields($item->describe());

        if (0 === $action->execute()->count()) {
            return new \Yz_Hash();
        }

        $values = $action->fetchList();

        return $this->assignValues($values,$item);
    }

    /**
     *  @param Pagination
     *  @return Yz_Array[Yz_Item_Interface]
     */
    public function fetchPage($pagination)
    {
        debug();

        $item = $this->selectItem();

        $action = $this->selectAction('SelectList');
        $action
            ->setOffset($pagination->getPageOffset())
            ->setLimit($pagination->getPageItems())
            ->assignFields($item->describe());

        $values = $action()->fetchList();

        $pagination->setItemCount($action->getFoundRows());

        return $this->assignValues($values,$item);
    }

    /************************************
     *       Protected methods          *
     ************************************/

    protected function assignValues($values, $item)
    {
        if (null === $values) {
            return new \Yz_Hash();
        }
        ### new: a result indexed by IDs can not be an Array, it is physically a hash
        $list = array();
        foreach ($values as $value) {
            $item0 = clone $item;
            $list[$value->id] = $item0->assignValues($value);
        }
        return new \Yz_Hash($list);
        ### old
        return $values->map(function($index,$value) use ($item) {
            $item0 = clone $item;
            return $item0->assignValues($value);
        });
    }

}
